package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.BlackOrWhiteMapper;
import com.sd365.permission.centre.entity.BlackOrWhite;
import com.sd365.permission.centre.pojo.dto.BlackOrWhiteDTO;
import com.sd365.permission.centre.pojo.query.BlackOrWhiteQuery;
import com.sd365.permission.centre.pojo.vo.BlackOrWhiteVO;
import com.sd365.permission.centre.pojo.vo.UserVO;
import com.sd365.permission.centre.service.BlackOrWhiteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

import static org.springframework.util.Assert.isTrue;
import static org.springframework.util.Assert.notEmpty;

@Service
public class BlackOrWhiteServiceImpl extends AbstractBaseDataServiceImpl implements BlackOrWhiteService {

    @Autowired
    private BlackOrWhiteMapper blackOrWhiteMapper;

    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private BlackOrWhiteService blackOrWhiteService;


    @Override
    public List<BlackOrWhiteVO> commonQuery(BlackOrWhiteQuery blackOrWhiteQuery) {

        List<BlackOrWhite> blackOrWhites = blackOrWhiteMapper.commonQuery(blackOrWhiteQuery);
        if (!CollectionUtils.isEmpty(blackOrWhites)) {
            if (blackOrWhiteQuery.getId() == null) {
                Page page = (Page) blackOrWhites;
                BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            }
            return BeanUtil.copyList(blackOrWhites, BlackOrWhiteVO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    BlackOrWhite entity = (BlackOrWhite) o;
                    BlackOrWhiteVO vo = (BlackOrWhiteVO) o1;
                    if (entity.getUser() != null) {
                        BeanUtil.copy(entity.getUser(), vo.getUserVO(), UserVO.class);
                    }
                }
            });
        }
        return new ArrayList<>();
    }


    @Override
    public BlackOrWhiteVO add(BlackOrWhiteDTO blackOrWhiteDTO) {
        BlackOrWhite blackOrWhite = BeanUtil.copy(blackOrWhiteDTO, BlackOrWhite.class);
//        Object o = redisTemplate.opsForValue().get(blackOrWhite.getBlackOrWhiteAccount());
        blackOrWhite.setId(idGenerator.snowflakeId());
        blackOrWhite.setVersion(1L);
        super.baseDataStuff4Add(blackOrWhite);
        super.baseDataStuffCommonPros(blackOrWhite);
        if (blackOrWhiteMapper.insert(blackOrWhite) > 0) {
            return BeanUtil.copy(blackOrWhite, BlackOrWhiteVO.class);
        } else return null;
    }

    @Override
    public Boolean remove(Long id, Long version) {
        BlackOrWhite blackOrWhite = blackOrWhiteMapper.selectByPrimaryKey(id);
        blackOrWhiteService.removeCache(blackOrWhite.getBlackOrWhiteAccount());
        return blackOrWhiteMapper.deleteByPrimaryKey(id) > 0;
    }



    @Override
    public Boolean removeCache(String account) {
        return true;
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean batchRemove(BlackOrWhiteDTO[] blackOrWhiteDTOS) {
        notEmpty(blackOrWhiteDTOS, "批量删除参数不可以为空");
        for (BlackOrWhiteDTO blackOrWhiteDTO : blackOrWhiteDTOS) {
            BlackOrWhite copy = BeanUtil.copy(blackOrWhiteDTO, BlackOrWhite.class);
            int result = blackOrWhiteMapper.deleteByPrimaryKey(copy);
            isTrue(result > 0, String.format("删除的记录id %d 没有匹配到版本", blackOrWhiteDTO.getId()));
        }
        return true;
    }

    @Override
    public Boolean modify(BlackOrWhiteDTO blackOrWhiteDTO) {
        BlackOrWhite copy = BeanUtil.copy(blackOrWhiteDTO, BlackOrWhite.class);
        Object o = redisTemplate.opsForValue().get(copy.getBlackOrWhiteAccount());
        super.baseDataStuff4Updated(copy);
        return blackOrWhiteMapper.updateByPrimaryKeySelective(copy) > 0;
    }

    @Transactional
    @Override
    public Boolean batchModify(BlackOrWhiteDTO[] blackOrWhiteDTOS) {
        Assert.noNullElements(blackOrWhiteDTOS, "更新数组不能为空");
        for (BlackOrWhiteDTO blackOrWhiteDTO : blackOrWhiteDTOS) {
            BlackOrWhite blackOrWhite = BeanUtil.copy(blackOrWhiteDTO, BlackOrWhite.class);
            Example example = new Example(blackOrWhite.getClass());
            example.createCriteria().andEqualTo("id", blackOrWhite.getId()).andEqualTo("version", blackOrWhite.getVersion());

            super.baseDataStuff4Updated(blackOrWhite);
//            int result=blackOrWhiteMapper.updateByExampleSelective(blackOrWhite,example);
//            Assert.isTrue(result>0,"没有找到相应id更新记录");
        }
        return true;
    }

    @Override
    public BlackOrWhiteDTO queryById(Long id) {
        try {
            BlackOrWhiteDTO blackOrWhiteDTO = null;
            BlackOrWhite blackOrWhite = blackOrWhiteMapper.selectByPrimaryKey(id);
            if (blackOrWhite != null) {
                blackOrWhiteDTO = BeanUtil.copy(blackOrWhite, BlackOrWhiteDTO.class);
            }
            return blackOrWhiteDTO;
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        }
    }

    @Override
    public BlackOrWhiteVO queryTest(BlackOrWhiteQuery query) {
        List<BlackOrWhiteVO> blackOrWhiteVOS = this.commonQuery(query);
        if (!CollectionUtils.isEmpty(blackOrWhiteVOS)) {
            return blackOrWhiteVOS.get(0);
        }
        return new BlackOrWhiteVO();
    }

    @Transactional
    @Override
    public Boolean batchAdd(List<BlackOrWhiteDTO> blackOrWhiteDTOList) {
        try {
            blackOrWhiteDTOList.stream().forEach(item -> {
                this.add(item);
            });
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}
